package com.xiaofengstu.mcams.interceptor;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaofengstu.mcams.constant.SysConstants;

import com.xiaofengstu.mcams.exception.BizException;
import com.xiaofengstu.mcams.util.JwtUtils;
import com.xiaofengstu.mcams.util.RedisUtils;
import com.xiaofengstu.mcams.util.ThreadLocalUtils;
import com.xiaofengstu.mcams.web.entity.TUser;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

/**
 * @author FengZeng
 * @Date 2022年5月10日18:27:40
 */
@Configuration
@RequiredArgsConstructor
@Slf4j
public class MyInterceptor implements HandlerInterceptor {

  private final JwtUtils jwtUtil;

  private final RedisUtils redisUtil;

  private final ObjectMapper objectMapper;


  /**
   * @return 返回 true 放行、放回 false 拦截
   */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
    //过滤掉 确认的 options 请求
    if (SysConstants.HTTP_OPTION_REQUEST.equals(request.getMethod())) {
      return true;
    }

    String token = request.getHeader(SysConstants.TOKEN);

    long expire = 0L;
    TUser currentUser = null;

    try {

      if (token == null) {
        throw new BizException(-1, SysConstants.INVALID_TOKEN);
      }
      currentUser = jwtUtil.getCurrentUser(token);

      expire = redisUtil.getExpire(String.valueOf(currentUser.getUserId()));

      if (expire < 0) {
        throw new BizException(-1, SysConstants.INVALID_TOKEN);
      }

    } catch (BizException e) {
      log.error("token异常,ip: {}",request.getRemoteHost());
      PrintWriter out = response.getWriter();

      out.write(objectMapper.writeValueAsString(new HashMap<String, String>(8) {
        {
          put("code", "500");
          put("msg", "token is invalid");
        }
      }));
      return false;
    }

    if (expire < SysConstants.FIVE_MINUTE) {
      redisUtil.cacheValue(String.valueOf(currentUser.getUserId()), token, SysConstants.HALF_HOUR);
    }
    ThreadLocalUtils.set(currentUser.getUserId());
    return true;
  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    ThreadLocalUtils.remove();
  }
}
